#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 1024

struct Person
{
	char name[40];
	char phone[20];
	struct Person *next;
};

struct Person *pool = NULL;
int count;

void getInput(struct Person *person);
void printPerson(struct Person *person);
void addPerson(struct Person **contacts);
void changPerson(struct Person *contacts);
void delPerson(struct Person **contacts);
struct Person *findPerson(struct Person *contacts);
void displayContacts(struct Person *contacts);
void releaseContacts(struct Person **contacts);
void releasePool(void);


void getInput(struct Person *person)
{
	printf("请输入姓名：");
	scanf("%s",person->name);
	printf("请输入电话：");
	scanf("%s",person->phone);
}


void addPerson(struct Person **contacts)
{
	struct Person *person;
	struct Person *temp;
	
	// 如果内存池非空，则直接从里面获取空间
	if (pool != NULL)	
	{
		person = pool;
		pool = pool->next;
		count--;
	}
	// 如果内存池为空，则调用malloc函数申请新的内存空间
	else
	{
		person = (struct Person *)malloc(sizeof(struct Person));
		if (person == NULL)
		{
			printf("内存分配失败！\n");
			exit(1);
		}
	}
	getInput(person);
	
	// 将person用头插法添加到通讯录中
        if (*contacts != NULL)
        {
                temp = *contacts;
		// 定义单链表尾部位置
		while ( temp->next !=NULL)
		{
			temp = temp->next;
		}
		// 插入数据
		temp->next = person;
		person->next = NULL;
        }
        else
        {
                *contacts = person;
                person->next = NULL;
        }
	

}


void printPerson(struct Person *person)
{
	printf("联系人：%s\n",person->name);
	printf("电话：%s\n",person->phone);
}

struct Person *findPerson(struct Person *contacts)
{
	struct Person *current;
	char input[40];
	
	printf("请输入联系人：");
	scanf("%s",input);
	
	current = contacts;
	while (current != NULL && strcmp(current->name,input))
	{
		current = current->next;
	}	
	
	return current;
}

void changPerson(struct Person *contacts)
{
	struct Person *person;
	
	person = findPerson(contacts);
	if (person == NULL)
	{
		printf("找不到该联系人！\n");
	}
	else
	{
		printf("请输入新的联系电话：");
		scanf("%s",person->phone);
	}

	
}

void delPerson(struct Person **contacts)
{
	struct Person *temp;	
	struct Person *person;	
	struct Person *current;	
	struct Person *previous;	
	
	// 先找待删除的节点指针
	person = findPerson(*contacts);
	if (person == NULL)
	{
		printf("找不到该联系人！\n");
	}
	else
	{
		current = *contacts;
		previous = NULL;
		
		// current定位到待删除的节点
		while (current != NULL && current != person)
		{
			previous = current;
			current = current->next;
		}

		if (previous == NULL)
        	{
        	        *contacts = current->next;
        	}
        	else
        	{
        	        previous->next = current->next;
        	}
		
		// 判断内存池是不是有空位
		if (count < MAX)
		{
			if (pool != NULL)
			{
				temp = pool;
				pool = person;
				person->next = temp;
			}
			else
			{
				pool = person;
				person->next = NULL;
			}
			count++;
		}
		else
		{	
			free(person);	
		}
	}

}

void displayContacts(struct Person *contacts)
{
	struct Person *current;	
	
	current = contacts;
	while (current != NULL)
	{
		printPerson(current);
		current = current->next;
	}
}

void releaseContacts(struct Person **contacts)
{
	struct Person *temp;	

	while (*contacts != NULL)
	{
                temp = *contacts;
		*contacts = (*contacts)->next;
		free(temp);
	}
}

void releasePool(void)
{
	struct Person *temp;	

	while (pool != NULL)
	{
                temp = pool;
		pool = pool->next;
		free(temp);
	}
	
}

int main()
{
	int code;
	struct Person *contacts = NULL;	
	struct Person *person;	
	
	printf("| 欢迎使用通讯录管理程序 -|\n");
	printf("|--- 1:插入新的联系人 ---|\n");
	printf("|--- 2:查找已有联系人 ---|\n");
	printf("|--- 3:更改已有联系人 ---|\n");
	printf("|--- 4:删除已有联系人 ---|\n");
	printf("|--- 5:显示已有联系人 ---|\n");
	printf("|--- 6:退出通讯录程序 ---|\n");
	printf("|- xxxxxxxxxxxxxxxxx -|\n");
	
	while (1)
	{
		printf("\n请输入指令代码：");
		scanf("%d", &code);
		switch (code)
		{
			case 1: addPerson(&contacts); break;
			
			case 2: person = findPerson(contacts);
				if (person == NULL)
				{
					printf("找不到该联系人！\n");
				}
				else
				{	
					printPerson(person);
				}
				break;

			case 3: changPerson(contacts); break;


			case 4: delPerson(&contacts); break;

			case 5: displayContacts(contacts); break;

			case 6: goto END;
		}
		
	}	

END:
	releaseContacts(&contacts);
	releasePool();

	return 0;
}
